IFs and LOOPs
We need to look at the code that compilers generate for high-level constructs like IF and WHILE
Let's start with the IF statement and see what actually happens
if (x < y) {
STUFF
}
- STUFF will be executed if x < y
- it will be skipped if x !< y
- branches implement skips so the code will be
bnlt x y end
whatever code is generated by STUFF
end:
- there is no such thing as bnlt, so we need to put the right thing in its place
- !< is the same as ≥
- so this is what we end up with
bge x y end
whatever code is generated by STUFF
end:
Let's double-check to make sure that this really does the right thing
- if x < y the branch will not be taken
- if the branch is not taken, the STUFF code will be executed
- so far, so good
- if x !< y then x ≥ y
- the branch will be taken
- the code for STUFF will be skipped
- again, this is the right thing
- there are no other possibilities to consider, so it does the right thing in all cases
- take a minute to ponder on why bgt is the wrong thing here
What if the IF has an ELSE??
if (x < y) {
SOMESTUFF
}
else {
OTHERSTUFF
}
- STUFF will be executed if x < y, and OTHERSTUFF will be skipped
- STUFF will be skipped if x !< y, and OTHERSTUFF will be executed
- here is some code that is close, but it has a problem
bge x y else
whatever code is generated by SOMESTUFF
else: whatever code is generated by OTHERSTUFF
- if x < y, it will do SOMESTUFF, as it should
- then it will do OTHERSTUFF, which it should not
- we have to insert a jump instruction to fix this
bge x y else
whatever code is generated by SOMESTUFF
j end
else: whatever code is generated by OTHERSTUFF
end:
Let's double-check to make sure that this really does the right thing
- if x < y the branch will not be taken
- if the branch is not taken, the SOMESTUFF code will be executed
- then the code for OTHERSTUFF will be skipped because of the jump
- so far, so good
- if x !< y then x ≥ y
- the branch will be taken
- the code for SOMESTUFF will be skipped
- the code for OTHERSTUFF will be executed
- again, this is the right thing
- there are no other possibilities to consider, so it does the right thing in all cases
What about WHILE loops?
while (x < y) {
STUFF
}
- the test is at the top of the loop
- if the test fails right at the beginning, STUFF will not be executed at all,
so the loop will execute zero times
- therefore our loop code needs to start with a branch
lp: bge x y end
whatever code is generated by STUFF
j lp
end:
Let's double-check to make sure that this really does the right thing
- if x !< y when we arrive at the top of the loop, we will take the branch and exit the loop
- so far, so good
- if x < y when we arrive at the top of the loop, we will not take the branch and STUFF will be executed
- after STUFF finishes, we jump back to the top and redo the test
- this does the right thing in both cases, and they are the only possible cases